package com.saibo.spider.gather.service;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.saibo.spider.commons.ConnectServer;
import com.saibo.spider.gather.Submitable;
import com.saibo.spider.main.MainControl;
import com.saibo.spider.utils.StringUtil;
import com.saibowisdom.base.api.aspirator.model.InfoClassMap;
import com.saibowisdom.base.api.aspirator.model.TableDef;
import com.saibowisdom.base.api.aspirator.model.TaskEntry;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.log4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPOutputStream;

public class ThreadService implements Runnable,Submitable {

	Map<String, Object> sourceMap;
	InfoClassMap infoMap;
	String url;
	static ObjectMapper  objectMapper = new ObjectMapper();
	boolean bRun =false;
	Logger log = Logger.getLogger(ThreadService.class);

	public ThreadService(Map<String, Object> sourceMap) {
		this.sourceMap = sourceMap;
	}

	public synchronized boolean isRun(){
		return bRun;
	}
	private  synchronized void setRun(boolean brun){
		bRun = brun;
	}
	public void run() {
		setRun(true);
		while (true){
			try {
				Thread.sleep(5000);
				String sid = sourceMap.get("sourceID").toString();
				log.info("获取到信源ID:" + sid+ "\tMac Address:" + MainControl.MACADDRESS);
				String url = MainControl.schedulerAddr+"/services/schedule/obtainEntryInfo";
				Map<String, String> spiderInfo = new HashMap<String, String>();
				spiderInfo.put("macaddr", MainControl.MACADDRESS);
				spiderInfo.put("sourceId", sid);
				String responseValue = ConnectServer.sendPostRequest(url, JSON.toJSONString(spiderInfo));
				if (!StringUtil.isNullOrEmpty(responseValue)) {
					@SuppressWarnings("unchecked")
					List<Map<String, Object>> lmso = (List<Map<String, Object>>) MainControl.missionMap.get("infoClassMapList");

					Map<String, Object> param = StringUtil.jsonToMap(responseValue);

					TaskEntry taskEntry = objectMapper.readValue(responseValue, TaskEntry.class);
					if(taskEntry == null){
						setRun(false);
						return;
					}

					Integer actionID = taskEntry.getActionID();

					Integer sourceID = Integer.parseInt(sid);
					InfoClassMap icm = MainControl.getInstance().getInfoClassMap(sourceID, actionID);

					String entryUrl = taskEntry.getEntryUrl();

					this.setInfoClassMap(icm);
					log.info("【任务URL】" + entryUrl);

					this.url = entryUrl;
					Class<?> class1 = null;
					try {
						class1 = Class.forName("com.saibo.spider.gather." + icm.getClassName());
						Method method = class1.getMethod("startMission",String.class,String.class,Submitable.class);
						method.invoke(class1.newInstance(), entryUrl ,JSON.toJSONString(taskEntry),this);
					} catch (Exception e) {
						e.printStackTrace();
						//setRun(false);
					}
				}
			} catch (Exception e){
				e.printStackTrace();
				log.error(e.getMessage());
				//setRun(false);
			}
			setRun(false);
		}


	}

	public void setInfoClassMap(InfoClassMap infoMap) {
		this.infoMap = infoMap;
	}

	public void submitD(String jsonData) throws IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(MainControl.schedulerAddr+"/services/schedule/addEntry4http");

		StringEntity params = new StringEntity(jsonData.toString());
		params.setContentEncoding("UTF-8");
		httpPost.setEntity(params);

		CloseableHttpResponse res = httpclient.execute(httpPost);

		System.out.println("发送结果响应码:" + res.getStatusLine().getStatusCode());
		System.out.println("发送结果返回值为:" + res.getEntity().getContent().toString());
	}

	public boolean submitTaskEntry(String action, List<TaskEntry> lstEntry) {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(MainControl.schedulerAddr+"/services/schedule/addEntry4http");
		Integer  actionID = MainControl.getInstance().getActionIDbyName(infoMap.getSourceID(), action);

		for(TaskEntry te: lstEntry){
			te.setActionID(actionID);
		}
		String jsonData = JSON.toJSONString(lstEntry);

		StringEntity params = null;
		try {
			params = new StringEntity(jsonData);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		params.setContentEncoding("UTF-8");
		httpPost.setEntity(params);

		try {
			CloseableHttpResponse res = httpclient.execute(httpPost);
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	static void submitData(String jsonData){
		CloseableHttpClient httpclient = HttpClients.createDefault();
		/*RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(10000).setSocketTimeout(10000)
				.setConnectionRequestTimeout(10000).setRedirectsEnabled(false).build();*/

		String submitAddr = MainControl.submitUrl+"/addNewsDataListGzip.do";

		//HttpPost httpPost = new HttpPost("http://submitdata.saibowisdom.com/addNewsDataListGzip.do");
		HttpPost httpPost = new HttpPost(submitAddr);
		//httpPost.setConfig(requestConfig);
		httpPost.setHeader("Connection", "keep-alive");
		httpPost.setHeader("Accept", "text/plain");
		//httpPost.setHeader("Transfer-Encoding", "chunked");

		ByteArrayOutputStream baos = null;
		GZIPOutputStream gzipOut = null;
		try {
			ByteArrayOutputStream originalContent = new ByteArrayOutputStream();
			originalContent
					.write(jsonData.getBytes(Charset.forName("UTF-8")));

			baos = new ByteArrayOutputStream();
			gzipOut = new GZIPOutputStream(baos);
			originalContent.writeTo(gzipOut);


			gzipOut.finish();
			byte[] byteArray = baos.toByteArray();
			httpPost.setHeader("contentLength", String.valueOf(byteArray.length));
			httpPost.setEntity(new ByteArrayEntity(byteArray, ContentType.TEXT_PLAIN));
			CloseableHttpResponse httpResponse = httpclient.execute(httpPost);
			System.out.println(httpResponse.getStatusLine().getStatusCode());
		} catch (IOException e) {
			e.printStackTrace();
			return;
		} finally {
			try {
				gzipOut.close();
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public  boolean submit(String status, List<Map<String, Object>> data) {
		if(status.equalsIgnoreCase("ok")){
			TableDef td = infoMap.getTableDef();
			String tablename = td.getTableName();
			Map<String, Object> dataMap = new HashMap<String, Object>();
			dataMap.put("TABLE", tablename);
			dataMap.put("_SOURCE", this.url);
			dataMap.put("DATA", data);
			dataMap.put("intoBloom", 1);
			submitData(JSON.toJSONString(dataMap));
			return true;
		}
		return false;
	}
}
